package org.datas {
	import flash.utils.Dictionary;
	import org.core.CoreObject;

	/**
	 * Map
	 * @author Kinglong(kinglong@gmail.com)
	 * @since:2010-9-22
	 * 键值对，无初始化值
	 */
	public class Map extends CoreObject implements IMap {
		private var _keys:Array;
		private var _dict:Dictionary;

		public function Map(){
			_keys = [];
			_dict = new Dictionary();
		}

		public function clear():void {
			_keys = [];
			_dict = new Dictionary();
		}

		public function containsKey(key:*):Boolean {
			return _keys.indexOf(key) != -1;
		}

		public function containsValue(value:*):Boolean {
			for each (var item:*in _dict){
				if (item == value){
					return true;
				}
			}
			return false;
		}

		public function get(key:*):* {
			return _dict[key];
		}

		public function put(key:*, value:*):* {
			var result:* = null;
			if (containsKey(key)){ //若值已存在
				result = get(key);
				_dict[key] = value;
			} else {
				_keys.push(key);
				_dict[key] = value;
			}
			return result;
		}

		public function remove(key:*):* {
			var result:* = null;
			if (containsKey(key)){
				result = _dict[key];
				delete _dict[key];
				var index:int = _keys.indexOf(key);
				if (index != -1){
					_keys.splice(index, 1);
				}
			}
			return result;
		}

		public function putAll(map:IMap):void {
			clear();
			var len:uint = map.size;
			if (len > 0){
				var keys:Array = map.keys;
				for (var i:uint = 0; i < len; i++){
					put(keys[i], map.get(keys[i]));
				}
			}
		}

		public function get size():uint {
			return _keys.length;
		}

		public function isEmpty():Boolean {
			return _keys.length == 1;
		}

		public function get keys():Array {
			return _keys.concat();
		}

		public function get values():Array {
			var result:Array = new Array(size);
			var len:uint = size;
			if (len > 0){
				for each (var item:*in _dict){
					result.push(item);
				}
			}
			return result;
		}

		override public function toString():String {
			return "[" + getClassName() + " size=" + size + "]";
		}

		override public function equals(object:*):Boolean {
			// TODO: Auto-generated method stub
			if (object == this){
				return true;
			}
			if (!(object is IMap)){
				return false;
			}
			var om:IMap = object as IMap;
			if (om.size != size){
				return false;
			}
			for each (var key:*in _keys){
				if (get(key) != om.get(key)){
					return false;
				}
			}
			return true;
		}

		override public function clone():* {
			var map:Map = new Map();
			map.putAll(this);
			return map;
		}
	}
}